import 'package:dio/dio.dart';
import 'package:enjoy_plus/models/http_model.dart';
import 'package:enjoy_plus/utils/eventbus.dart';
import 'package:enjoy_plus/utils/logger.dart';
import 'package:enjoy_plus/utils/toast.dart';
import 'package:enjoy_plus/utils/token.dart';

class NetworkService {
  final _dio = Dio();

  NetworkService() {
    _dio.options.baseUrl = 'https://live-api.itheima.net';
    _dio.options.connectTimeout = const Duration(seconds: 10);
    _dio.options.receiveTimeout = const Duration(seconds: 5);
    _dio.options.headers = {'Content-Type': 'application/json'};
    _addInterceptors();
  }

  // GET 方法泛型改造
  Future<ApiResponse<T>> get<T>(
    String url, {
    Map<String, dynamic>? params,
    required T Function(dynamic) fromJson,
  }) async {
    try {
      // 如果url是以http或https开头,就直接使用完整url喵
      final isFullUrl = url.startsWith('http://') || url.startsWith('https://');
      final requestUrl = isFullUrl ? url : _dio.options.baseUrl + url;

      logger.d(requestUrl);
      logger.d(params);

      Response response = await _dio.get(requestUrl, queryParameters: params);

      return ApiResponse<T>.fromJson(response.data, fromJson);
    } catch (e) {
      final error = handleError(e);
      return error;
    }
  }

  // POST 方法泛型改造
  Future<ApiResponse<T>> post<T>(
    String url, {
    required dynamic data,
    required T Function(dynamic) fromJson,
  }) async {
    try {
      final response = await _dio.post(url, data: data);
      // 直接转换成 ApiResponse<T> 对象
      return ApiResponse<T>.fromJson(response.data, fromJson);
    } catch (e) {
      // 错误处理也返回 ApiResponse
      final error = handleError(e);
      return error;
    }
  }

  //PUT
  Future<ApiResponse<T>> put<T>(
    String url, {
    required dynamic data,
    required T Function(dynamic) fromJson,
  }) async {
    try {
      final response = await _dio.put(url, data: data);
      return ApiResponse<T>.fromJson(response.data, fromJson);
    } catch (e) {
      final error = handleError(e);
      return error;
    }
  }

  //DELETE
  Future<ApiResponse<T>> delete<T>(
    String url, {
    required T Function(dynamic) fromJson,
  }) async {
    final response = await _dio.delete(url);
    return ApiResponse<T>.fromJson(response.data, fromJson);
  }

  //拦截器
  void _addInterceptors() {
    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) {
        // 请求拦截器：添加公共请求参数、token 等
        final token = TokenManager().getToken() ?? '';
        if (token.isNotEmpty) {
          options.headers['Authorization'] = 'Bearer $token';
        }
        return handler.next(options);
      },
      onResponse: (response, handler) {
        // 响应拦截器：统一处理成功响应
        return handler.next(response);
      },
      onError: (DioException error, handler) {
        // 响应拦截器：统一处理错误响应
        return handler.next(error);
      },
    ));
  }

  //处理响应
  dynamic handleResponse(Response response) {
    if (response.statusCode! >= 200 && response.statusCode! < 300) {
      return response.data;
    } else {
      throw Exception('请求失败，状态码：${response.statusCode}');
    }
  }

  //处理错误
  dynamic handleError(e) {
    if (e is DioException) {
      if (e.type == DioExceptionType.connectionTimeout ||
          e.type == DioExceptionType.receiveTimeout) {
        throw Exception('请求超时，请稍后再试');
      } else if (e.type == DioExceptionType.badResponse) {
        if (e.response?.statusCode == 401) {
          TokenManager().removeToken();
          // 通过事件通知登录页面退出登录
          eventBus.fire(LogoutEvent(''));
          ToastUtil.showError('请重新登录');
        } else {
          throw Exception('响应错误，状态码：${e.response?.statusCode}');
        }
      } else {
        throw Exception('请求失败，错误：$e');
      }
    } else {
      throw Exception('请求失败，错误：$e');
    }
  }
}

final http = NetworkService();
